<template>
  <form class="validate-form-container">
    <slot name="default"></slot>
    <div class="submit-area d-grid" @click.prevent="formSubmit()">
      <slot name="submit">
        <button type="submit" class="btn btn-primary">提交</button>
      </slot>
    </div>
  </form>
</template>

<script lang='ts'>
import { defineComponent, onUnmounted } from 'vue'
import mitt from 'mitt'

type validateFunc = () => Promise<boolean>;

type clearFunc = () => void;

type Events = {
  'push:validateFunc': validateFunc;
  'push:clearFunc': clearFunc;
};

export const emitter = mitt<Events>()

export default defineComponent({
  name: 'ValidateForm',
  emits: ['form-submit'],
  setup (props, context) {
    let validateFuncs: validateFunc[] = []

    let clearFuncs: clearFunc[] = []

    const formSubmit = () => {
      const results: Promise<boolean>[] = []
      validateFuncs.forEach((f) => {
        results.push(f())
      })
      Promise.all(results).then((res) => {
        let result = true
        res.forEach((r) => {
          if (!r) {
            result = false
          }
        })
        context.emit('form-submit', result)
      })
      // if (!result) {
      //   clearFuncs.forEach(f => {
      //     f()
      //   })
      // }
    }

    const callback = (func: validateFunc) => {
      validateFuncs.push(func)
    }

    const clearPush = (func: clearFunc) => {
      clearFuncs.push(func)
    }

    // 事件监听器要在触发之前就设置好，否则就会错过监听时机
    emitter.on('push:validateFunc', callback)
    emitter.on('push:clearFunc', clearPush)

    onUnmounted(() => {
      emitter.off('push:validateFunc', callback)
      validateFuncs = []
      emitter.off('push:clearFunc', clearPush)
      clearFuncs = []
    })

    return {
      formSubmit
    }
  }
})
</script>
